package com.yuanli.card.manage.service;

import com.yuanli.card.authentication.core.PasswordUtil;
import com.yuanli.card.authentication.service.ISysUserService;
import com.yuanli.card.constant.ResponseCode;
import com.yuanli.card.enumeration.UserTypeEnum;
import com.yuanli.card.exception.ServiceException;
import com.yuanli.card.mapper.SysUserMapper;
import com.yuanli.card.pojo.SysUser;
import com.yuanli.card.pojo.UserRelationship;
import com.yuanli.card.req.SysUserQueryReq;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by layne on 2018/11/12.
 */
@Service
public class SysUserService implements ISysUserService {
    Logger logger = LoggerFactory.getLogger(SysUserService.class);
    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public void save(SysUser sysUser) {
        // 检查是否存在
        SysUser byUsername = sysUserMapper.findByUsername(sysUser.getUsername());
        if (byUsername != null) {
            logger.warn(ResponseCode.USER_EXSIT_ERROR.des());
            throw new ServiceException(ResponseCode.USER_EXSIT_ERROR);
        }
        //添加账号类型为客户
        sysUser.setUser_type(UserTypeEnum.CUSTOMER.name());
        SysUser userSession = (SysUser) SecurityUtils.getSubject().getSession().getAttribute("userSession");
        if (userSession == null) {
            throw new ServiceException(405, "未登录");
        }
        sysUser.setParent_id(userSession.getId());
        // 密码加密
        try {
            PasswordUtil.Salt salt = PasswordUtil.encrypt(sysUser.getUsername(), sysUser.getPassword());
            sysUser.setPassword(salt.password)
                    .setSalt(salt.salt);
        } catch (Exception e) {
            logger.error(ResponseCode.PASSWORD_ENCRYPT_ERROR.des());
            throw new ServiceException(ResponseCode.PASSWORD_ENCRYPT_ERROR);
        }
        sysUserMapper.save(sysUser);
    }


    @Override
    public SysUser findByUserName(String username) {
        return sysUserMapper.findByUsername(username);
    }

    @Override
    public void updateUserLastLoginInfoById(Long userId) {
        Date date = new Date();
        sysUserMapper.updateUserLastLoginInfoById(userId, date);
    }

    @Override
    public SysUser findById(Long userId) {
        return sysUserMapper.findById(userId);
    }

    @Override
    public void login(SysUser sysUser) {
        UsernamePasswordToken token = new UsernamePasswordToken(sysUser.getUsername(), sysUser.getPassword());
        //获取当前的Subject
        Subject currentUser = SecurityUtils.getSubject();
        try {
            currentUser.login(token);
        } catch (LockedAccountException lae) {
            token.clear();
            logger.warn(ResponseCode.ACCOUNT_LOCKED.des());
            throw new ServiceException(ResponseCode.ACCOUNT_LOCKED);
        } catch (ExcessiveAttemptsException e) {
            token.clear();
            logger.warn(ResponseCode.ACCOUNT_LOCKED.des());
            throw new ServiceException(ResponseCode.ACCOUNT_LOCKED);
        } catch (UnknownAccountException e) {
            token.clear();
            logger.error(ResponseCode.ACCOUNT_NOT_EXSIT_ERROR.des());
            throw new ServiceException(ResponseCode.ACCOUNT_NOT_EXSIT_ERROR);
        } catch (AuthenticationException e) {
            token.clear();
            logger.error(ResponseCode.PASSWORD_NOT_CORRECT.des());
            throw new ServiceException(ResponseCode.PASSWORD_NOT_CORRECT);
        }
    }

    @Override
    public void delSysUser(Long id) {
        sysUserMapper.delById(id);
    }

    @Override
    public void update(SysUser sysUser) {
        sysUserMapper.update(sysUser);
    }

    @Override
    public List<SysUser> listChild(SysUserQueryReq req) {
        SysUser userSession = (SysUser) SecurityUtils.getSubject().getSession().getAttribute("userSession");
        return Optional.ofNullable(userSession)
                .map(sysUser -> {
                    req.setId(userSession.getId());
                    return sysUserMapper.listChild(req);
                })
                .orElseThrow(() -> new ServiceException(405, "未登录"));
    }

    @Override
    public List<SysUser> listAll() {
        return sysUserMapper.listAll();
    }

    /**
     * 获取当前用户
     *
     * @return
     */
    public SysUser currentUser() {
        SysUser userSession = (SysUser) SecurityUtils.getSubject().getSession().getAttribute("userSession");
        return Optional.ofNullable(userSession)
                .orElseThrow(() -> new ServiceException(405, "未登录"));
    }

    /**
     * 获取当前用户所有级别用户id
     *
     * @return
     */
    @Override
    public List<Integer> getAllChildId() {
        SysUser userSession = (SysUser) SecurityUtils.getSubject().getSession().getAttribute("userSession");
        return Optional.ofNullable(userSession)
                .map(sysUser -> levelChild(userSession.getId().intValue()))
                .orElseThrow(() -> new ServiceException(405, "未登录"));
    }

    /**
     * 获取当前用户直接下级用户id
     *
     * @return
     */
    @Override
    public List<Integer> getChildId() {
        SysUser userSession = (SysUser) SecurityUtils.getSubject().getSession().getAttribute("userSession");
        return Optional.ofNullable(userSession)
                .map(sysUser -> sysUserMapper.findChildById(sysUser.getId().intValue()))
                .orElseThrow(() -> new ServiceException(405, "未登录"));
    }


    private List<Integer> levelChild(Integer parentId) {
        List<Integer> childIds = sysUserMapper.findChildById(parentId);
        if (childIds == null || childIds.isEmpty()) {
            return Collections.emptyList();
        }
        List<Integer> result = new ArrayList<>(childIds);
        childIds.forEach(id -> result.addAll(this.levelChild(id)));
        return result;
    }
}
